package pacman.entries.pacman.meta_graph.features;

import pacman.entries.pacman.meta_graph.IMetaGraphFeature;
import pacman.entries.pacman.meta_graph.IMetaGraphObject;
import pacman.entries.pacman.meta_graph.MetaGraphNode;
import pacman.entries.pacman.meta_graph.MetaGraphPath;
import pacman.game.Constants.DM;
import pacman.game.Constants.GHOST;
import pacman.game.Game;
/**
 * Indicator of whether or not PacMan can beat ghosts to each node in the path.
 */
public class PathFeatureCanBeatInedibleGhosts implements IMetaGraphFeature {
	
	private final float PENALTY = 25.0f;
	
	private float considerNode(MetaGraphNode node, Game game) {
		double pacDistance = game.getDistance(game.getPacmanCurrentNodeIndex(), node.MazeIndex(),
				DM.PATH);
		float score = 0.0f;
		
		for (GHOST ghost : GHOST.values()) {
			// don't be afraid of an edible ghost
			if (game.getGhostEdibleTime(ghost) > 0.0f)
				continue;
			
			double ghostDistance = game.getDistance(game.getGhostCurrentNodeIndex(ghost),
					node.MazeIndex(), game.getGhostLastMoveMade(ghost), DM.PATH);
			if (ghostDistance < pacDistance)
				score -= PENALTY;
		}
		
		return score;
	}
	
	@Override
	public float Evaluate(IMetaGraphObject object, Game game) {
		
		MetaGraphPath path = (MetaGraphPath) object;
		
		float score = 0.0f;
		
		while (path != null) {
			if (path.Edge() == null)
				score += considerNode(path.Node(), game);
			else
				score += considerNode(path.Edge().getOppositeNodeOf(path.Node()), game);
			
			path = path.Next();
		}
		
		return score;
	}

}
